package com.dht.xiao.jianye.utils;

import android.os.Handler;

import com.dht.xiao.jianye.base.serialport.utils.ByteUtil;
import com.dht.xiao.jianye.command.Protocol;

import java.nio.ByteBuffer;

/**
 * 数据接收器实现类
 * author: John
 * create time: 2018/7/5 14:15
 * description:
 */
public abstract class DataReceiverImpl implements DataReceiver {

    private Handler mHandler;
    private final ByteBuffer mByteBuffer;
    private HexTool mHexTool = HexTool.getInstance();

    public DataReceiverImpl(Handler handler) {
        mHandler = handler;
        mByteBuffer = ByteBuffer.allocate(2048);
        mByteBuffer.clear();
    }

    @Override
    public void onReceive(final byte[] bytes, int offset, int length) {

        //LogPlus.i("接收数据=" + ByteUtil.bytes2HexStr(bytes, offset, length));
//9D7F 7E77 3300 8A01 0311 99
        // SYN RES PTROL ADDR SLEN COMMAND APPDATA CRC16
        // 2   3   1     2    2    2       *       2    字节
       // 2 + 3 + 1 + 2 + 2 + 2 + 2
        // 1个字节对应字符串2位
        // 最少 14 个字节

        try{
            mByteBuffer.put(bytes, offset, length);
            mByteBuffer.flip();

            byte b;
            int readable;
            byte[] twoBytes = new byte[2];
            byte[] lenby = new byte[1];
            // 标记一个第一个元素

            while ((readable = mByteBuffer.remaining()) >= Protocol.MIN_PACK_LEN) {
                mByteBuffer.mark(); // 标记一下开始的位置
                int frameStart = mByteBuffer.position();

                b = mByteBuffer.get();
                if (b != Protocol.FRAME_HEAD_0) { // 第1个byte要3A
                    continue;
                }

                b = mByteBuffer.get();
                if (b != Protocol.FRAME_HEAD_1) { // 第2个byte要A3
                    continue;
                }

                // 跳过 RES PTROL ADDR (3 1 2)
                mByteBuffer.position(mByteBuffer.position() + 2);

                // 数据长度SLEN
                mByteBuffer.get(lenby);
                //  LogPlus.e("数据长度=" + mByteBuffer.toString());
                final int slen = (int) ByteUtil.hexStr2decimal(ByteUtil.bytes2HexStr(lenby));
                // slen包括command和appdata，所以要把command的两字节减去
                int total = slen;
                // 如果可读数据小于总数据长度，表示不够,还有数据没接收
                if (readable < total) {
                    // 重置一下要处理的位置,并跳出循环
                    mByteBuffer.reset();
                    break;
                }
                // 跳过 (COMMAND+APPDATA)=SLEN
                // 找到crc16
                mByteBuffer.position(mByteBuffer.position()+slen-6);
                mByteBuffer.get(lenby);

                String crc16 = ByteUtil.bytes2HexStr(lenby).toUpperCase();
                // 回到头
                mByteBuffer.reset();
                // 拿到整个包
                final byte[] data = new byte[total];
                mByteBuffer.get(data);
                String orcrc =  ByteUtil.bytes2HexStr(data).toUpperCase();
                LogToFile.e("读到完整命令="+orcrc);
                orcrc = orcrc.substring(0,orcrc.length() -2);
                /// LogPlus.e("orcrc=" + orcrc );
                String otherCrc16 = mHexTool.getXOR(orcrc);

                // LogPlus.e("crc16=" + crc16 + ",other_crc16=" + otherCrc16);
                 LogToFile.e("crc16=" + crc16 + ",other_crc16=" + otherCrc16);
                if (crc16.equals(otherCrc16)) {
                    // 校验成功
                    Runnable runnable = new Runnable() {
                        @Override
                        public void run() {
                            String command = ByteUtil.bytes2HexStr(data, 6, 1);
                            //byte[] appdata = new byte[slen - 2];
                            //System.arraycopy(data,  0, appdata.length);
                            //// 所有数据
                            LogToFile.e("验证之后数据="+data);
                            onReceive(command, data);
                        }
                    };

                    if (mHandler != null) {
                        mHandler.post(runnable);
                    } else {
                        runnable.run();
                    }
                } else {
                    // 不一致则回到“第二位”，继续找到下一个3AA3
                    mByteBuffer.position(frameStart + 2);
                }
            }

            // 最后清掉之前处理过的不合适的数据
            mByteBuffer.compact();
        }catch (Exception e){
            // 最后清掉之前处理过的不合适的数据
            mByteBuffer.compact();
        }

    }

    public abstract void onReceive(String command, byte[] allData);
}
//45 9B 89 76